package com.rxyb.rabbitmq.toolmq.controller.aop;

import cn.hutool.core.thread.ThreadUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author YJH
 * @version 1.0
 * @description
 * @date 2020/7/2 11:15
 */
@Component
@Aspect
@Slf4j
public class Test {


    /**
     * 定义切入点，切入点为com.example.demo.aop.AopController中的所有函数
     * 通过@Pointcut注解声明频繁使用的切点表达式
     */
    @Pointcut(value = "execution(* com.rxyb.rabbitmq.toolmq.controller.*.*(..))")
    public void pointcut() {
    }


    /**
     * 在连接点执行之前执行的通知
     *
     * @param joinPoint
     */
    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        log.info("前置通知:" + joinPoint.getThis());

        ThreadPoolExecutor threadPoolExecutor = ThreadUtil.newExecutor(3, 10);
        threadPoolExecutor.execute(() -> {
            ThreadUtil.sleep(3000, TimeUnit.MILLISECONDS);
            log.info("我操作了其他信息1");
            log.info("当前有【{}】线程", threadPoolExecutor.getPoolSize());
        });
        threadPoolExecutor.execute(() -> {
            ThreadUtil.sleep(2000, TimeUnit.MILLISECONDS);
            log.info("我操作了其他信息2");
        });

        threadPoolExecutor.execute(() -> {
            ThreadUtil.sleep(2000, TimeUnit.MILLISECONDS);
            log.info("我操作了其他信3");
        });
        log.info("当前有【{}】线程", threadPoolExecutor.getPoolSize());
    }


    /**
     * @description 在连接点执行之后执行的通知（返回通知）
     */
    @AfterReturning("pointcut()")
    public void doAfterReturningGame(JoinPoint joinPoint) {
        System.out.println("返回通知：经纪人为球星表现疯狂鼓掌！" + joinPoint.getTarget());
    }

    /**
     * @description 在连接点执行之后执行的通知（异常通知）
     */
    @AfterThrowing("pointcut()")
    public void doAfterThrowingGame() {
        System.out.println("异常通知：球迷要求退票！");
    }
}